#include "SolarSystemModel.h"
#include <QDebug>
#include <QDateTime>
#include <QtMath>

SolarSystemModel::SolarSystemModel(QObject *parent)
    : QAbstractListModel(parent)
    , m_timeSpeed(1.0f)
    , m_isRunning(true)
    , m_startTime(QDateTime::currentDateTime())
{
    initializePlanets();
    
    // 设置动画定时器 - 使用60 FPS获得更流畅的动画
    m_animationTimer = new QTimer(this);
    connect(m_animationTimer, &QTimer::timeout, this, &SolarSystemModel::updateAnimation);
    m_animationTimer->start(16); // ~60 FPS (16ms per frame)
}

void SolarSystemModel::initializePlanets()
{
    m_planets.clear();
    
    // 基准时间：2000年1月1日 12:00 UTC (J2000.0)
    QDateTime j2000 = QDateTime::fromString("2000-01-01T12:00:00", Qt::ISODate);
    j2000.setTimeSpec(Qt::UTC);
    
    // 计算从J2000到现在的天数
    qint64 daysSinceJ2000 = j2000.daysTo(QDateTime::currentDateTime());
    
    // 水星 (参考位置：J2000时的平黄经)
    m_planets.append({
        "Mercury", "水星",
        0.38f, 0.39f, 88.0f, 58.6f,
        QVector3D(0.8f, 0.6f, 0.4f),
        fmod(252.25f + daysSinceJ2000 * 360.0f / 88.0f, 360.0f), 
        0.0f, true
    });
    
    // 金星
    m_planets.append({
        "Venus", "金星",
        0.95f, 0.72f, 225.0f, 243.0f,
        QVector3D(1.0f, 0.8f, 0.2f),
        fmod(181.98f + daysSinceJ2000 * 360.0f / 225.0f, 360.0f),
        0.0f, true
    });
    
    // 地球
    m_planets.append({
        "Earth", "地球",
        1.0f, 1.0f, 365.25f, 1.0f,
        QVector3D(0.2f, 0.6f, 1.0f),
        fmod(100.46f + daysSinceJ2000 * 360.0f / 365.25f, 360.0f),
        0.0f, true
    });
    
    // 火星
    m_planets.append({
        "Mars", "火星",
        0.53f, 1.52f, 687.0f, 1.03f,
        QVector3D(0.8f, 0.3f, 0.2f),
        fmod(355.45f + daysSinceJ2000 * 360.0f / 687.0f, 360.0f),
        0.0f, true
    });
    
    // 木星
    m_planets.append({
        "Jupiter", "木星",
        11.2f, 5.20f, 4333.0f, 0.41f,
        QVector3D(0.9f, 0.7f, 0.5f),
        fmod(34.40f + daysSinceJ2000 * 360.0f / 4333.0f, 360.0f),
        0.0f, true
    });
    
    // 土星
    m_planets.append({
        "Saturn", "土星",
        9.4f, 9.58f, 10759.0f, 0.44f,
        QVector3D(0.9f, 0.8f, 0.6f),
        fmod(49.94f + daysSinceJ2000 * 360.0f / 10759.0f, 360.0f),
        0.0f, true
    });
    
    // 天王星
    m_planets.append({
        "Uranus", "天王星",
        4.0f, 19.22f, 30687.0f, 0.72f,
        QVector3D(0.6f, 0.8f, 1.0f),
        fmod(313.23f + daysSinceJ2000 * 360.0f / 30687.0f, 360.0f),
        0.0f, true
    });
    
    // 海王星
    m_planets.append({
        "Neptune", "海王星",
        3.9f, 30.05f, 60190.0f, 0.67f,
        QVector3D(0.3f, 0.5f, 1.0f),
        fmod(304.88f + daysSinceJ2000 * 360.0f / 60190.0f, 360.0f),
        0.0f, true
    });
    
}

int SolarSystemModel::rowCount(const QModelIndex &parent) const
{
    Q_UNUSED(parent)
    return m_planets.size();
}

QVariant SolarSystemModel::data(const QModelIndex &index, int role) const
{
    if (!index.isValid() || index.row() < 0 || index.row() >= m_planets.size())
        return QVariant();

    const Planet &planet = m_planets.at(index.row());
    switch (role) {
    case NameRole: return planet.name;
    case ChineseNameRole: return planet.chineseName;
    case RadiusRole: return planet.radius;
    case DistanceRole: return planet.distance;
    case OrbitalPeriodRole: return planet.orbitalPeriod;
    case RotationPeriodRole: return planet.rotationPeriod;
    case ColorRole: return QVariant::fromValue(planet.color);
    case CurrentAngleRole: return planet.currentAngle;
    case RotationAngleRole: return planet.rotationAngle;
    case IsVisibleRole: return planet.isVisible;
    default: return QVariant();
    }
}

QHash<int, QByteArray> SolarSystemModel::roleNames() const
{
    return {
        {NameRole, "name"},
        {ChineseNameRole, "chineseName"},
        {RadiusRole, "radius"},
        {DistanceRole, "distance"},
        {OrbitalPeriodRole, "orbitalPeriod"},
        {RotationPeriodRole, "rotationPeriod"},
        {ColorRole, "color"},
        {CurrentAngleRole, "currentAngle"},
        {RotationAngleRole, "rotationAngle"},
        {IsVisibleRole, "isVisible"}
    };
}

void SolarSystemModel::updatePlanetPositions()
{
    QDateTime currentTime = QDateTime::currentDateTime();
    calculatePlanetPositions(currentTime);
}

void SolarSystemModel::togglePlanetVisibility(int index)
{
    if (index >= 0 && index < m_planets.size()) {
        m_planets[index].isVisible = !m_planets[index].isVisible;
        QModelIndex modelIndex = this->index(index, 0);
        emit dataChanged(modelIndex, modelIndex, {IsVisibleRole});
    }
}

void SolarSystemModel::resetToCurrentTime()
{
    m_startTime = QDateTime::currentDateTime();
    
    // 重新初始化行星位置到当前真实日期
    initializePlanets();
    
    // 通知所有数据已更新
    beginResetModel();
    endResetModel();
}

void SolarSystemModel::setTimeSpeed(float speed)
{
    if (qFuzzyCompare(m_timeSpeed, speed))
        return;
    
    m_timeSpeed = qBound(0.1f, speed, 100.0f);
    emit timeSpeedChanged();
}

float SolarSystemModel::timeSpeed() const
{
    return m_timeSpeed;
}

bool SolarSystemModel::isRunning() const
{
    return m_isRunning;
}

void SolarSystemModel::setIsRunning(bool running)
{
    if (m_isRunning == running)
        return;
    
    m_isRunning = running;
    if (running) {
        m_animationTimer->start();
    } else {
        m_animationTimer->stop();
    }
    emit isRunningChanged();
}

void SolarSystemModel::updateAnimation()
{
    if (!m_isRunning)
        return;
    
    // 计算从启动时间到现在经过的天数（应用时间加速）
    QDateTime currentTime = QDateTime::currentDateTime();
    qint64 elapsedMs = m_startTime.msecsTo(currentTime);
    
    // 时间加速效果：每秒真实时间 = (timeSpeed/10)天，更温和的速度
    float elapsedDays = (elapsedMs / 10000.0f) * m_timeSpeed;
    
    // 计算真实日期（从初始化时刻开始）
    QDateTime j2000 = QDateTime::fromString("2000-01-01T12:00:00", Qt::ISODate);
    j2000.setTimeSpec(Qt::UTC);
    qint64 baseDays = j2000.daysTo(m_startTime);
    float totalDays = baseDays + elapsedDays;
    
    static int debugCounter = 0;
    debugCounter++;
    
    for (int i = 0; i < m_planets.size(); ++i) {
        Planet &planet = m_planets[i];
        
        // 使用实际的J2000平黄经作为基础，加上从那时起的运动
        float baseAngle = 0.0f;
        switch (i) {
            case 0: baseAngle = 252.25f; break; // 水星
            case 1: baseAngle = 181.98f; break; // 金星
            case 2: baseAngle = 100.46f; break; // 地球
            case 3: baseAngle = 355.45f; break; // 火星
            case 4: baseAngle = 34.40f; break;  // 木星
            case 5: baseAngle = 49.94f; break;  // 土星
            case 6: baseAngle = 313.23f; break; // 天王星
            case 7: baseAngle = 304.88f; break; // 海王星
        }
        
        // 计算当前角度：基础角度 + 从J2000到现在的运动
        planet.currentAngle = fmod(baseAngle + totalDays * 360.0f / planet.orbitalPeriod, 360.0f);
        
        // 计算自转角度 - 使用较慢的速度以获得更好的视觉效果
        // 自转速度为实际速度的1/5，避免高速播放时自转过快
        float rotationDays = baseDays + (elapsedDays * 0.2f);  // 只用20%的时间加速
        planet.rotationAngle = fmod(rotationDays * 360.0f / planet.rotationPeriod, 360.0f);
        
        // 动画更新（每60帧）
    }
    
    // 通知数据变化
    emit dataChanged(index(0, 0), index(m_planets.size() - 1, 0), 
                     {CurrentAngleRole, RotationAngleRole});
}

void SolarSystemModel::calculatePlanetPositions(const QDateTime &currentTime)
{
    // 这里可以实现更精确的天体位置计算
    // 目前使用简化的开普勒轨道模型
    updateAnimation();
}

QVariantMap SolarSystemModel::get(int index) const
{
    QVariantMap map;
    if (index >= 0 && index < m_planets.size()) {
        const Planet &planet = m_planets.at(index);
        map["name"] = planet.name;
        map["chineseName"] = planet.chineseName;
        map["radius"] = planet.radius;
        map["distance"] = planet.distance;
        map["orbitalPeriod"] = planet.orbitalPeriod;
        map["rotationPeriod"] = planet.rotationPeriod;
        map["color"] = QVariant::fromValue(planet.color);
        map["currentAngle"] = planet.currentAngle;
        map["rotationAngle"] = planet.rotationAngle;
        map["isVisible"] = planet.isVisible;
    }
    return map;
}
